/** 
 * @file   ScoringM2M.cc
 * @author Scanagatta Mauro - Alberto Franco
 * 
 * Multiple sequence scoring class implementation
 */
#include <ScoringM2M.h>

namespace Biopool
{

// CONSTRUCTORS:

ScoringM2M::ScoringM2M(SubMatrix *sub,vector<string>* leftSeq, 
    vector<string>* rightSeq, AlignmentData* ad, double cSeq) :
        ScoringScheme(sub, ad, 0), leftSeq(leftSeq), 
        rightSeq(rightSeq), cSeq(cSeq)
{ }


ScoringM2M::ScoringM2M(const ScoringM2M &orig) : ScoringScheme(orig)
{
	copy(orig);
}


ScoringM2M::~ScoringM2M()
{ }


// OPERATORS:

ScoringM2M&
ScoringM2M::operator = (const ScoringM2M &orig)
{
	if (&orig != this)
		copy(orig);
	return *this;
}


// PREDICATES:

double
ScoringM2M::scoring(int i, int j)
{
	double s = 0.0;
	size_t N = rightSeq->size(), M = leftSeq->size();
    
    /// For each sequence alignment give a score and then divide by 1 /(N + M)
    for (size_t left_i = 0; left_i < M; left_i++)
        for (size_t right_i = 0; right_i < N; right_i++)
        {
            char l = ((*leftSeq)[left_i])[i - 1];
            char r = ((*rightSeq)[right_i])[j - 1];
            
            s += sub->score[l][r];
        }
    s = (s * cSeq) / (N + M);
    
	return s;
}


// MODIFIERS:

void
ScoringM2M::copy(const ScoringM2M &orig)
{
	ScoringScheme::copy(orig);
	cSeq = orig.cSeq;
	
	leftSeq   = orig.leftSeq;
	rightSeq  = orig.rightSeq;
}


ScoringM2M*
ScoringM2M::newCopy()
{
	ScoringM2M *tmp = new ScoringM2M(*this);
	return tmp;
}


void
ScoringM2M::reverse()
{
	ScoringScheme::reverse();

	for (size_t j = 0; j < leftSeq->size(); j++)
	{
	    string tmp = "";    
	    for (unsigned int i = (*leftSeq)[j].length(); i > 0; i--)
		    tmp.push_back((*leftSeq)[j][i-1]);
	    (*leftSeq)[j] = tmp;
    }
}

} // namespace
